package com.kma.summer2012.server;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.kma.summer2012.client.ExceptionHandling.CrumbsRPCServiceException;
import com.kma.summer2012.client.MD5Hasher;
import com.kma.summer2012.client.services.user.CrumbsUserService;
import com.kma.summer2012.dao.CrumbsUserDAO;
import com.kma.summer2012.facade.PasswordRecoveryFacade;
import com.kma.summer2012.factory.DAOFactory;
import com.kma.summer2012.factory.SpringBeansFactory;
import com.kma.summer2012.model.CrumbsUser;
import com.kma.summer2012.server.proxy.Proxy;
import com.kma.summer2012.shared.model.UICrumbsUser;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class CrumbsUserServiceImpl extends RemoteServiceServlet implements CrumbsUserService {


    public UICrumbsUser getById(int id) throws CrumbsRPCServiceException {
        DAOFactory factory = SpringBeansFactory.getInstance().getBeanByClass(DAOFactory.class);
        try {
            return Proxy.getInstance().createFromUser((CrumbsUser) factory.getCrumbsUserDAO().getById(id));
        }
        catch (Exception e) {
            System.out.println("Exception was caught");
            throw new CrumbsRPCServiceException("Getting the user from DataBase failed.", e);
        }
    }

    @Override
    public void update(int id, String password) throws CrumbsRPCServiceException {
        DAOFactory factory = SpringBeansFactory.getInstance().getBeanByClass(DAOFactory.class);
        try {
            CrumbsUser user = (CrumbsUser) factory.getCrumbsUserDAO().getById(id);
            user.setPassword(MD5Hasher.getInstance().getHash(password));
            factory.getCrumbsUserDAO().update(user);
        } catch (Exception e) {
            throw new CrumbsRPCServiceException("Apdating the password failed.", e);
        }
    }

    public List<UICrumbsUser> getAllUsers() throws CrumbsRPCServiceException {
        List<UICrumbsUser> uiCrumbsUsers = new ArrayList<UICrumbsUser>();
        DAOFactory factory = (DAOFactory) SpringBeansFactory.getInstance().getBeanByName("daoFactory");
        CrumbsUserDAO dao = (CrumbsUserDAO) factory.getCrumbsUserDAO();
        try {
            for (CrumbsUser user : dao.getAll()) {
                uiCrumbsUsers.add(Proxy.getInstance().createFromUser(user));
            }
        } catch (Exception e) {
            throw new CrumbsRPCServiceException("Getting the list of users from DataBase failed.", e);
        }
        return uiCrumbsUsers;
    }


    public UICrumbsUser getByLoginPassword(String login, String password) throws CrumbsRPCServiceException {
        DAOFactory factory = (DAOFactory) SpringBeansFactory.getInstance().getBeanByClass(DAOFactory.class);
        CrumbsUserDAO dao = (CrumbsUserDAO) factory.getCrumbsUserDAO();
        try {
            CrumbsUser user = dao.searchByLoginPassword(login, MD5Hasher.getInstance().getHash(password));
            if (user != null) {
                return Proxy.getInstance().createFromUser(user);
            } else return null;
        } catch (Exception e) {
            throw new CrumbsRPCServiceException("Error in connection to database", e);
        }
    }

    @Override
    public UICrumbsUser getByLogin(String login) throws CrumbsRPCServiceException {
        DAOFactory factory = (DAOFactory) SpringBeansFactory.getInstance().getBeanByClass(DAOFactory.class);
        CrumbsUserDAO dao = (CrumbsUserDAO) factory.getCrumbsUserDAO();
        try {
            return Proxy.getInstance().createFromUser(dao.searchByLogin(login));
        } catch (Exception e) {
            throw new CrumbsRPCServiceException("Error in connection to database", e);
        }
    }

    @Override
    public Boolean sendMailRecovery(String mail, String path) throws CrumbsRPCServiceException {
        PasswordRecoveryFacade facade = SpringBeansFactory.getInstance().getBeanByClass(PasswordRecoveryFacade.class);
        Boolean res = false;
        try {
            facade.sendMail(mail, path);
            res= true;
        } catch (Exception e) {
            throw new CrumbsRPCServiceException("Error in sending mail", e);
        }
        return res;
    }


    public List<UICrumbsUser> getAllEngineers() throws CrumbsRPCServiceException {
        List<UICrumbsUser> uiCrumbsUsers = new ArrayList<UICrumbsUser>();
        DAOFactory factory = (DAOFactory) SpringBeansFactory.getInstance().getBeanByName("daoFactory");
        CrumbsUserDAO dao = (CrumbsUserDAO) factory.getCrumbsUserDAO();
        try {
            for (CrumbsUser user : dao.getAllEngineers()) {
                uiCrumbsUsers.add(Proxy.getInstance().createFromUser(user));
            }
        } catch (Exception e) {
            throw new CrumbsRPCServiceException("Getting the list of engineers from DataBase failed.", e);
        }
        return uiCrumbsUsers;
    }


    @Override
    public UICrumbsUser checkLogin() {

        HttpServletRequest request = this.getThreadLocalRequest();
        // dont create a new one -> false
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute("User") == null)
            return null;
        // session and userid is available, looks like user is logged in.
        return (UICrumbsUser) session.getAttribute("User");
    }

    @Override
    public void login(UICrumbsUser user) {
        HttpServletRequest request = this.getThreadLocalRequest();
        HttpSession session = request.getSession(true);
        session.setAttribute("User", user);
    }

    @Override
    public void logout() {

        HttpServletRequest request = this.getThreadLocalRequest();
        // dont create a new one -> false
        HttpSession session = request.getSession(false);
        if (session == null)
            return;
        // do some logout stuff ...
        session.invalidate();
    }

}
